package com.qaml.mes.device.domain.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.earth.except.error.BusinessException;
import com.earth.page.PageResponse;
import com.qaml.mes.device.api.*;
import com.qaml.mes.device.dao.EqpAttachmentDO;
import com.qaml.mes.device.dao.EqpAuxiliaryStuffDO;
import com.qaml.mes.device.dao.EqpInfoDO;
import com.qaml.mes.device.enums.BizErrorEnums;
import com.qaml.mes.device.repository.EqpAttachmentRepository;
import com.qaml.mes.device.repository.EqpAuxiliaryStuffRepository;
import com.qaml.mes.device.repository.EqpInfoRepository;
import com.qaml.mes.device.utils.BASE64DecodedMultipartFile;
import com.qaml.mes.device.utils.OssUploadFileUtil;
import com.qaml.mes.device.utils.QrCodeUtil;
import com.qaml.mes.device.domain.convert.EqpAttachmentConvert;
import com.qaml.mes.device.domain.convert.EqpAuxiliaryStuffConvert;
import com.qaml.mes.device.domain.convert.EqpInfoConvert;
import com.qaml.mes.device.dto.eqp.*;
import com.qaml.mes.device.enums.AttachmentTypeEnum;
import com.qaml.mes.device.enums.UseStatusEnum;
import com.qaml.mes.device.vo.eqp.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 设备信息表 服务实现类
 * </p>
 *
 * @author leikai
 * @since 2024-02-27
 */
@Service
public class EqpInfoServiceImpl implements EqpInfoService {

    @Resource
    private EqpInfoRepository eqpInfoRepository;

    @Resource
    private EqpAttachmentRepository eqpAttachmentRepository;

    @Resource
    private EqpAuxiliaryStuffRepository eqpAuxiliaryStuffRepository;

    @Resource
    private EqpAttachmentService eqpAttachmentService;

    @Resource
    private EqpAuxiliaryStuffService eqpAuxiliaryStuffService;

    @Resource
    private CheckUpkeepInfoService checkUpkeepInfoService;

    @Resource
    private EqpTypeConfigService eqpTypeConfigService;

    @Resource
    private QrCodeUtil rCodeUtil;

    /**
     * 保存或更新设备信息
     *
     * @param eqpInfoDTO 设备信息DTO对象
     */
    @Override
    public void saveOrUpdate(EqpInfoDTO eqpInfoDTO) {
        // 将设备信息DTO对象转换为设备信息DO对象
        EqpInfoDO eqpInfoDO = EqpInfoConvert.INSTANCE.saveDTO(eqpInfoDTO);
        if (StringUtils.isNotBlank(eqpInfoDO.getEqpCode())) {
            String base64QRCode = rCodeUtil.getBase64QRCode(eqpInfoDO.getEqpCode());
            // 转换为二维码图片
            MultipartFile multipartFile = BASE64DecodedMultipartFile.base64ToMultipart(base64QRCode);
            String twoDimensionalCode = OssUploadFileUtil.fileUpload(multipartFile);
            eqpInfoDO.setTwoDimensionalCode(twoDimensionalCode);
        }
        try {
            if (StringUtils.isNotBlank(eqpInfoDO.getId())) {
                eqpInfoRepository.update(eqpInfoDO);
            } else {
                eqpInfoRepository.save(eqpInfoDO);
            }
        } catch (DuplicateKeyException e) {
            throw new BusinessException(BizErrorEnums.EQP_CODE_ALREADY_EXISTS);
        }
        List<EqpAuxiliaryStuffDTO> eqpAuxiliaryStuffDTOList = eqpInfoDTO.getEqpAuxiliaryStuffDTOList();
        if (eqpAuxiliaryStuffDTOList != null && !eqpAuxiliaryStuffDTOList.isEmpty()) {
            List<EqpAuxiliaryStuffDO> eqpAuxiliaryStuffDOS = EqpAuxiliaryStuffConvert.INSTANCE.dto2DOList(eqpAuxiliaryStuffDTOList);
            eqpAuxiliaryStuffDOS.forEach(eqpAuxiliaryStuffDO -> {
                eqpAuxiliaryStuffDO.setEqpId(eqpInfoDO.getId());
            });
            eqpAuxiliaryStuffRepository.deleteByEqpId(eqpInfoDO.getId());
            eqpAuxiliaryStuffRepository.saveBatch(eqpAuxiliaryStuffDOS);
        }
        List<EqpAttachmentDTO> eqpAttachmentDTOList = getEqpAttachmentDTOS(eqpInfoDTO);
        // 如果设备附件DTO列表不为空，则删除设备附件，并保存设备附件
        if (!eqpAttachmentDTOList.isEmpty()) {
            List<EqpAttachmentDO> eqpAttachmentDOS = EqpAttachmentConvert.INSTANCE.dto2DOList(eqpAttachmentDTOList);
            eqpAttachmentRepository.deleteByEqpId(eqpInfoDO.getId());
            eqpAttachmentDOS.forEach(eqpAttachmentDO -> {
                eqpAttachmentDO.setEqpId(eqpInfoDO.getId());
            });
            eqpAttachmentRepository.saveBatch(eqpAttachmentDOS);
        }
    }

    private static List<EqpAttachmentDTO> getEqpAttachmentDTOS(EqpInfoDTO eqpInfoDTO) {
        List<EqpAttachmentDTO> eqpAttachmentDTOList = new ArrayList<>();
        List<EqpAttachmentDTO> eqpAttachmentFileList = eqpInfoDTO.getEqpAttachmentFileList();
        if (eqpAttachmentFileList != null && !eqpAttachmentFileList.isEmpty()) {
            eqpAttachmentFileList.forEach(eqpAttachmentDTO -> {
                eqpAttachmentDTO.setAttachmentType(AttachmentTypeEnum.FILE.getType());
            });
            eqpAttachmentDTOList.addAll(eqpAttachmentFileList);
        }
        List<EqpAttachmentDTO> eqpAttachmentImageList = eqpInfoDTO.getEqpAttachmentImageList();
        if (eqpAttachmentImageList != null && !eqpAttachmentImageList.isEmpty()) {
            eqpAttachmentImageList.forEach(eqpAttachmentDTO -> {
                eqpAttachmentDTO.setAttachmentType(AttachmentTypeEnum.IMAGE.getType());
            });
            eqpAttachmentDTOList.addAll(eqpAttachmentImageList);
        }
        return eqpAttachmentDTOList;
    }

    /**
     * 删除设备信息 --根据设备id
     *
     * @param id 设备ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(String id) {

        // 1. 获取设备信息
        EqpInfoDO eqpInfoDo = eqpInfoRepository.getById(id);
        // 1.1 添加判断，直接返回
        if (eqpInfoDo == null) {
            return;
        }
        // 2. 删除与设备相关的附件和辅助设备信息  -- 逻辑删除
        // 2.1 逻辑删除辅助设备
        eqpAttachmentService.deleteByEqpId(id);
        // 2.2 逻辑删除附件
        eqpAuxiliaryStuffService.deleteByEqpId(id);

        // 3. 标记设备为已删除
        eqpInfoDo.setIsDeleted(1);
        // 4. 更新设备信息（实质上是做标记删除操作）
        eqpInfoRepository.update(eqpInfoDo);

        // 5.对对应的检保项目做停用 根据设备id
        checkUpkeepInfoService.saveStatus(id);

    }

    /**
     * 根据设备id获取设备详情信息（包括设备附属物品以及附件）
     *
     * @param id
     * @return
     */
    @Override
    public EqpInfoVO getById(String id) {
        // 获取设备基本信息
        EqpInfoDO eqpInfoDO = eqpInfoRepository.getById(id);
        if (eqpInfoDO == null) {
            return null;
        }

        // DO -->VO
        EqpInfoVO eqpInfoVO = EqpInfoConvert.INSTANCE.do2VO(eqpInfoDO);
        // 查询设备附属物品
        List<EqpAuxiliaryStuffVO> eqpAuxiliaryStuffVOList = eqpAuxiliaryStuffService.getEqpAuxiliaryStuffVOList(id);
        // 查询设备附件
        List<EqpAttachmentVO> eqpAttachmentFileVOList = eqpAttachmentService.getEqpAttachmentList(id, AttachmentTypeEnum.FILE.getType());
        // 查询设备图片
        List<EqpAttachmentVO> eqpAttachmentImageVOList = eqpAttachmentService.getEqpAttachmentList(id, AttachmentTypeEnum.IMAGE.getType());
        // 将查询到的数据添加到VO中
        eqpInfoVO.setEqpAttachmentFileList(eqpAttachmentFileVOList);
        eqpInfoVO.setEqpAttachmentImageList(eqpAttachmentImageVOList);
        eqpInfoVO.setEqpAuxiliaryStuffVOList(eqpAuxiliaryStuffVOList);
        if (StringUtils.isNotBlank(eqpInfoVO.getCraftTypeCode())) {
            EqpCraftConfigVO craftConfigVO = eqpTypeConfigService.craftByCraftTypeCode(eqpInfoVO.getCraftTypeCode());
            eqpInfoVO.setCraftType(Objects.nonNull(craftConfigVO) ? craftConfigVO.getCraftType() : null);
        }

        return eqpInfoVO;

    }

    /**
     * 获取设备列表信息
     *
     * @return 设备列表信息
     */
    @Override
    public PageResponse<EqpInfoListVO> getEqpInfoVOList(EqpInfoListDTO eqpInfoListDTO) {
        // 1,将DTO转换为DO
        EqpInfoDO eqpInfoListDO = EqpInfoConvert.INSTANCE.listDO2DTO(eqpInfoListDTO);
        // 2.查询
        IPage<EqpInfoDO> page = eqpInfoRepository.page(eqpInfoListDTO.getPage(), eqpInfoListDTO.getPageSize(), eqpInfoListDO);
        // 3,如果分页对象的记录列表 不为空
        if (CollectionUtils.isEmpty(page.getRecords())) {
            // 4. 如果分页对象的记录列表为空，返回空的PageResponse对象
            return new PageResponse<>(0, null, eqpInfoListDTO);
        }
        Map<String, EqpCraftConfigVO> craftConfigVOMap = eqpTypeConfigService.craftMap();
        // 5,将查询结果转换为VO
        List<EqpInfoListVO> eqpInfoListVOS = EqpInfoConvert.INSTANCE.listDOs2VOs(page.getRecords());
        for (EqpInfoListVO eqpInfoListVO : eqpInfoListVOS) {
            EqpCraftConfigVO eqpCraftConfigVO = craftConfigVOMap.get(eqpInfoListVO.getCraftTypeCode());
            if (Objects.nonNull(eqpCraftConfigVO)) {
                eqpInfoListVO.setCraftType(eqpCraftConfigVO.getCraftType());
            }
        }
        return new PageResponse<>(page.getTotal(), eqpInfoListVOS, eqpInfoListDTO);
    }


    @Override
    public void enableEqp(EqpInfoIdDTO id) {
        EqpInfoDO eqpInfoDO = eqpInfoRepository.getByStatus(id, UseStatusEnum.DISABLED.getType());
        if (eqpInfoDO == null) {
            return;
        }
        eqpInfoDO.setStatus(UseStatusEnum.ENABLED.getType());
        eqpInfoRepository.update(eqpInfoDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void disableEqp(EqpInfoIdDTO id) {
        EqpInfoDO eqpInfoDO = eqpInfoRepository.getByStatus(id, UseStatusEnum.ENABLED.getType());
        if (eqpInfoDO == null) {
            throw new BusinessException(BizErrorEnums.NOT_DATA);
        }
        eqpInfoDO.setStatus(UseStatusEnum.DISABLED.getType());
        eqpInfoRepository.update(eqpInfoDO);
        // 对对应的检保项目做停用
        checkUpkeepInfoService.updateStatus(eqpInfoDO.getId());
    }

    /**
     * 获取设备列表
     *
     * @return
     */
    @Override
    public List<EqpInfoVO> getEqpCodeList() {
        List<EqpInfoDO> eqpCodeList = eqpInfoRepository.getEqpCodeList();
        return EqpInfoConvert.INSTANCE.dos2VOS(eqpCodeList);
    }
}




